use std::sync::Arc;
use sea_orm::DatabaseConnection;
use anyhow::Result;

use crate::config::Configs;
use crate::di::ServiceContainer;

/// 数据库服务
/// 
/// 封装数据库连接，提供线程安全的数据库访问
#[derive(Debug)]
pub struct DatabaseService {
    connection: Arc<DatabaseConnection>,
}

impl DatabaseService {
    /// 创建新的数据库服务实例
    pub fn new(connection: DatabaseConnection) -> Self {
        Self {
            connection: Arc::new(connection),
        }
    }

    /// 使用Arc<DatabaseConnection>创建新的数据库服务实例
    pub fn new_with_arc(connection: Arc<DatabaseConnection>) -> Self {
        Self { connection }
    }

    /// 获取数据库连接
    pub fn connection(&self) -> &DatabaseConnection {
        &self.connection
    }

    /// 获取数据库连接的Arc引用
    pub fn connection_arc(&self) -> Arc<DatabaseConnection> {
        Arc::clone(&self.connection)
    }
}

/// 配置服务
/// 
/// 封装应用配置，提供线程安全的配置访问
#[derive(Debug)]
pub struct ConfigService {
    config: Arc<Configs>,
}

impl ConfigService {
    /// 创建新的配置服务实例
    pub fn new(config: Configs) -> Self {
        Self {
            config: Arc::new(config),
        }
    }

    /// 获取配置
    pub fn config(&self) -> &Configs {
        &self.config
    }

    /// 获取配置的Arc引用
    pub fn config_arc(&self) -> Arc<Configs> {
        Arc::clone(&self.config)
    }
}

/// 扩展存储客户端服务
/// 
/// 封装扩展存储操作，提供线程安全的存储访问
#[derive(Debug)]
pub struct ExtensionStoreService {
    db_service: Arc<DatabaseService>,
}

impl ExtensionStoreService {
    /// 创建新的扩展存储服务实例
    pub fn new(db_service: Arc<DatabaseService>) -> Self {
        Self { db_service }
    }

    /// 获取数据库服务
    pub fn db_service(&self) -> &DatabaseService {
        &self.db_service
    }

    /// 获取数据库连接
    pub fn connection(&self) -> &DatabaseConnection {
        self.db_service.connection()
    }
}

/// 角色服务
/// 
/// 提供角色管理功能
#[derive(Debug)]
pub struct RoleService {
    store_service: Arc<ExtensionStoreService>,
}

impl RoleService {
    /// 创建新的角色服务实例
    pub fn new(store_service: Arc<ExtensionStoreService>) -> Self {
        Self { store_service }
    }

    /// 获取存储服务
    pub fn store_service(&self) -> &ExtensionStoreService {
        &self.store_service
    }

    /// 获取数据库连接
    pub fn connection(&self) -> &DatabaseConnection {
        self.store_service.connection()
    }
}

/// 用户服务
/// 
/// 提供用户管理功能
#[derive(Debug)]
pub struct UserService {
    store_service: Arc<ExtensionStoreService>,
    role_service: Arc<RoleService>,
    config_service: Arc<ConfigService>,
}

impl UserService {
    /// 创建新的用户服务实例
    pub fn new(
        store_service: Arc<ExtensionStoreService>,
        role_service: Arc<RoleService>,
        config_service: Arc<ConfigService>,
    ) -> Self {
        Self {
            store_service,
            role_service,
            config_service,
        }
    }

    /// 获取存储服务
    pub fn store_service(&self) -> &ExtensionStoreService {
        &self.store_service
    }

    /// 获取角色服务
    pub fn role_service(&self) -> &RoleService {
        &self.role_service
    }

    /// 获取配置服务
    pub fn config_service(&self) -> &ConfigService {
        &self.config_service
    }

    /// 获取数据库连接
    pub fn connection(&self) -> &DatabaseConnection {
        self.store_service.connection()
    }
}

/// 系统设置服务
/// 
/// 提供系统设置管理功能
#[derive(Debug)]
pub struct SystemSettingService {
    store_service: Arc<ExtensionStoreService>,
}

impl SystemSettingService {
    /// 创建新的系统设置服务实例
    pub fn new(store_service: Arc<ExtensionStoreService>) -> Self {
        Self { store_service }
    }

    /// 获取存储服务
    pub fn store_service(&self) -> &ExtensionStoreService {
        &self.store_service
    }

    /// 获取数据库连接
    pub fn connection(&self) -> &DatabaseConnection {
        self.store_service.connection()
    }
}

/// 附件服务
/// 
/// 提供文件附件管理功能
#[derive(Debug)]
pub struct AttachmentService {
    store_service: Arc<ExtensionStoreService>,
    config_service: Arc<ConfigService>,
}

impl AttachmentService {
    /// 创建新的附件服务实例
    pub fn new(
        store_service: Arc<ExtensionStoreService>,
        config_service: Arc<ConfigService>,
    ) -> Self {
        Self {
            store_service,
            config_service,
        }
    }

    /// 获取存储服务
    pub fn store_service(&self) -> &ExtensionStoreService {
        &self.store_service
    }

    /// 获取配置服务
    pub fn config_service(&self) -> &ConfigService {
        &self.config_service
    }

    /// 获取数据库连接
    pub fn connection(&self) -> &DatabaseConnection {
        self.store_service.connection()
    }
}

/// 服务注册器
/// 
/// 提供便捷的服务注册方法
pub struct ServiceRegistrar;

impl ServiceRegistrar {
    /// 注册所有核心服务到容器
    pub fn register_core_services(
        container: &ServiceContainer,
        db_connection: DatabaseConnection,
        config: Configs,
    ) -> Result<()> {
        // 将数据库连接包装在Arc中以便在闭包中使用
        let db_connection = Arc::new(db_connection);
        let db_connection_clone = Arc::clone(&db_connection);

        // 注册数据库服务（单例）
        container.register_singleton::<DatabaseService, _>(move |_| {
            // 使用Arc<DatabaseConnection>创建服务
            Ok(DatabaseService::new_with_arc(db_connection_clone.clone()))
        })?;

        // 注册配置服务（单例）
        let config_clone = config.clone();
        container.register_singleton::<ConfigService, _>(move |_| {
            Ok(ConfigService::new(config_clone.clone()))
        })?;

        // 注册扩展存储服务（单例）
        container.register_singleton::<ExtensionStoreService, _>(|container| {
            let db_service = container.resolve::<DatabaseService>()?;
            Ok(ExtensionStoreService::new(db_service))
        })?;

        // 注册角色服务（单例）
        container.register_singleton::<RoleService, _>(|container| {
            let store_service = container.resolve::<ExtensionStoreService>()?;
            Ok(RoleService::new(store_service))
        })?;

        // 注册用户服务（单例）
        container.register_singleton::<UserService, _>(|container| {
            let store_service = container.resolve::<ExtensionStoreService>()?;
            let role_service = container.resolve::<RoleService>()?;
            let config_service = container.resolve::<ConfigService>()?;
            Ok(UserService::new(store_service, role_service, config_service))
        })?;

        // 注册系统设置服务（单例）
        container.register_singleton::<SystemSettingService, _>(|container| {
            let store_service = container.resolve::<ExtensionStoreService>()?;
            Ok(SystemSettingService::new(store_service))
        })?;

        // 注册附件服务（单例）
        container.register_singleton::<AttachmentService, _>(|container| {
            let store_service = container.resolve::<ExtensionStoreService>()?;
            let config_service = container.resolve::<ConfigService>()?;
            Ok(AttachmentService::new(store_service, config_service))
        })?;

        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::config::{Configs, Server, DataBase, Log, Jwt, Cert};

    fn create_test_config() -> Configs {
        Configs {
            server: Server {
                name: "test".to_string(),
                address: "127.0.0.1:8080".to_string(),
                ssl: false,
            },
            database: DataBase {
                database_url: "sqlite::memory:".to_string(),
            },
            log: Log {
                filter_level: "info".to_string(),
                with_ansi: true,
                to_stdout: true,
                directory: "./logs".to_string(),
                file_name: "test.log".to_string(),
                rolling: "daily".to_string(),
            },
            jwt: Jwt {
                jwt_secret: "test_secret".to_string(),
                jwt_exp: 3600,
            },
            cert: Cert {
                cert: "test.pem".to_string(),
                key: "test.key".to_string(),
            },
        }
    }

    #[tokio::test]
    async fn test_service_creation() {
        // 这里只测试服务结构的创建，不涉及实际的数据库连接
        // 实际的集成测试需要在有数据库连接的环境中进行
        
        let config = create_test_config();
        let config_service = ConfigService::new(config);
        
        assert_eq!(config_service.config().server.name, "test");
        assert_eq!(config_service.config().server.address, "127.0.0.1:8080");
    }
}
